﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Linq;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Text;

namespace MedReg.Classes
{
    [Serializable]
    
    public class LPU : ISerializable, IEquatable<LPU>
    {
        private Guid idField;

        private Guid realIDField;

        private string nameField;

        private string iNNField;

 
        private string kPPField;

 
        private long LevelId;

        //private EntityRef<Level> lPULevelField;

        private Level lPULevelField;

        private long NomenId;

        //private EntityRef<Nomenclature> nomenField;
        
        
        private Nomenclature nomenField;
        
        //public int nomen_ID; // for DB


        private static readonly LPU theOneObject = new LPU();

        private Employee EmployeeField;
/*
        [OnDeserializing()]
        private void OnDeserializing(StreamingContext context)
        {

            this.Initialize();
        }


        private void Initialize()
        {
            _staffentry = new EntitySet<StaffEntry>(new Action<StaffEntry>(this.attach_StaffEntry), new Action<StaffEntry>(this.detach_StaffEntry));
            lPULevelField = default(EntityRef<Level>);
            nomenField = default(EntityRef<Nomenclature>);
        }
        private void attach_StaffEntry(StaffEntry entity)
        {
            
            entity.UZ = this;
        }

        private void detach_StaffEntry(StaffEntry entity)
        {
            
            entity.UZ = null;
        }
 */       
        public static LPU GetLPU()
        {
            return theOneObject;
        }
        /// <remarks/>
        
        public Guid ID
        {
            get
            {
                return this.idField;
            }
            set
            {
                this.idField = value;
            }
        }

        public Guid RealID
        {
            get
            {
                return realIDField;
            }
            set
            {
                realIDField = value;
            }
        }

        /// <remarks/>
        
        public string Name
        {
            get
            {
                return this.nameField;
            }
            set
            {
                this.nameField = value;
            }
        }

        /// <remarks/>
        
        public string INN
        {
            get
            {
                return this.iNNField;
            }
            set
            {
                this.iNNField = value;
            }
        }

        /// <remarks/>
        
        public string KPP
        {
            get
            {
                return this.kPPField;
            }
            set
            {
                this.kPPField = value;
            }
        }

        /// <remarks/>
        

        /// <remarks/>
        //[Column]

/*        
        [Association(Name = "LPU_StaffEntry_FK1", Storage = "_staffentry", ThisKey = "ID", OtherKey = "LPUId")]
        public EntitySet<StaffEntry> StaffEntries
        {
            get
            {
                return _staffentry;
            }
            set
            {
                _staffentry.Assign(value);
            }
        }

 */       

        //[Association(Name = "Level_LPU_FK1", IsForeignKey = true, Storage = "lPULevelField", ThisKey = "LevelId")]
        public Level LPULevel
        {
            get
            {
                return this.lPULevelField;
                //return lPULevelField.Entity;
            }
            set
            {
                this.lPULevelField = value;
                //lPULevelField.Entity = value;

/* 
                Level previosLevel = lPULevelField.Entity;
                Level newLevel = value;

                if (newLevel != previosLevel)
                {
                    // remove this LPU from prev
                    lPULevelField.Entity = null;
                    if (previosLevel != null)
                    {
                        previosLevel.LPU.Remove(this);
                    }
                    // set LPU to new
                    lPULevelField.Entity = newLevel;

                    if (newLevel != null)
                    {
                        newLevel.LPU.Add(this);
                    }
                }
*/
                
            }
        }

        /// <remarks/>
        //[Column]
        //[Association(Name = "Nomenclature_LPU_FK1", IsForeignKey = true, Storage = "nomenField", ThisKey = "NomenId")]
        public Nomenclature Nomen
        {
            get
            {
                return this.nomenField;
                //return nomenField.Entity;
            }
            set
            {
                this.nomenField = value;
                //nomenField.Entity = value;
                

/*                
                Nomenclature previosNome = nomenField.Entity;
                Nomenclature newNomen = value;

                
                if (newNomen != previosNome)
                {
                    // remove this LPU from prev
                    lPULevelField.Entity = null;
                    if (previosNome != null)
                    {
                        previosNome.LPU.Remove(this);
                    }
                    // set LPU to new
                    nomenField.Entity = newNomen;

                    if (newNomen != null)
                    {
                        newNomen.LPU.Add(this);
                    }
                }

*/                

            }
        }
        public Employee Employee
        {
            get
            {
                return EmployeeField;
            }
            set
            {
                EmployeeField = value;
            }

        }

        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            //throw new NotImplementedException();
            info.AddValue("ID", idField);
            info.AddValue("Name", nameField);
            info.AddValue("INN", iNNField);
            info.AddValue("KPP", kPPField);
            info.AddValue("LPULevel", lPULevelField);
            info.AddValue("Nomen", nomenField);
        }
        public LPU()
        {
//            Initialize();
        }


        /*
        public LPU(SerializationInfo info, StreamingContext context)
        {
            idField = (Guid) info.GetValue("ID", typeof (Guid));
            nameField = (string) info.GetValue("Name", typeof (string));
            iNNField = (string) info.GetValue("INN", typeof (string));
            kPPField = (string) info.GetValue("KPP", typeof (string));
            lPULevelField = (Level) info.GetValue("LPULevel", typeof (Level));
            nomenField = (Nomenclature) info.GetValue("Nomen", typeof (Nomenclature));

        }
         
        public LPU (Guid Id, string Name, string INN, string KPP, Level LPULevel, Nomenclature nomen)
        {
            this.idField = Id;
            this.nameField = Name;
            this.iNNField = INN;
            this.kPPField = KPP;
            this.lPULevelField = LPULevel;
            this.nomenField = nomen;
        }
        */

        public List<Classes.LPU> getLPUList(Classes.ArrayOfStaffEnrty staffEntryCollection)
        {

            var sLpu = new List<Classes.LPU>(from sc in staffEntryCollection select sc.UZ);
            
            var ssSub = sLpu
                .GroupBy(s => new { s.ID, s.Name, s.INN })
                .Select(g => g.First())
                .OrderBy(o => o.ID)
                .ToList();
            return ssSub;
        }

        public List<Classes.LPU> getLPUList(Classes.ArrayOfEmployee employeeCollection)
        {

            foreach (var emp in employeeCollection)
            {
                emp.UZ.Employee = emp;
                emp.UZ.RealID = (new MedReg.LPU()).GetRealID(emp.UZ);
            }
            var sLpu = new List<Classes.LPU>(from sc in employeeCollection select sc.UZ);
            
            var ssSub = sLpu
                .GroupBy(s => new { s.ID, s.Name, s.INN }) ////////////////
                .Select(g => g.First())
                .OrderBy(o => o.ID)
                .ToList();
            return ssSub;
        }
        public void FixLPUList(Classes.ArrayOfEmployee employeeCollection)
        {

            var dbLPU = new List<LPU>();
            
            foreach (var emp in employeeCollection)
            {
                emp.UZ.Employee = emp;
                var rID = (new MedReg.LPU()).GetRealID(emp.UZ);
                if (rID == Guid.Empty & !dbLPU.Contains(emp.UZ))
                {
                    rID = Guid.NewGuid();
                    emp.UZ.RealID = rID;
                    dbLPU.Add(emp.UZ);
                }
                emp.UZ.RealID = rID;
            }
            (new MedReg.LPU()).ImportList(dbLPU);
        }
        public bool Equals(LPU other)
        {
            var i = this.ID.Equals(other.ID);
            var j = this.Name.Equals(other.Name);
            var k = this.INN.Equals(other.INN);
            if (i & j & k)
            {
                return true;
            }
            return false;
        }

    }
   
}
